﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using Microsoft.WowAddonStudio.FrameXml.Components.Actions;
using Microsoft.WowAddonStudio.FrameXml.Components.Designers;
using Microsoft.WowAddonStudio.FrameXml.Components.Events;
using Microsoft.WowAddonStudio.FrameXml.Components.Support;
using Microsoft.WowAddonStudio.FrameXml.Serialization;
using Microsoft.WowAddonStudio.FrameXml.Serialization.LayoutFrames;
using Action=Microsoft.WowAddonStudio.FrameXml.Components.Actions.Action;

namespace Microsoft.WowAddonStudio.FrameXml.Components
{
    [ToolboxBitmap(typeof (Panel), "Panel.bmp")]
    [ToolboxItemFilter("WowAddonStudio", ToolboxItemFilterType.Require)]
    [Designer(typeof (LayoutFrameContainerDesigner))]
    [EventGroup(EventGroup.Frame, EventName.OnLoad)]
    public class FrameControl : LayoutFrameControl
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="FrameControl"/> class.
        /// </summary>
        public FrameControl()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="FrameControl"/> class.
        /// </summary>
        /// <param name="frame">The frame.</param>
        public FrameControl(Frame frame)
            : base(frame)
        {
        }

        /// <summary>
        /// Gets the type of the serialization object this control manages.
        /// </summary>
        public override Type SerializationObjectType
        {
            get { return typeof (Frame); }
        }

        /// <summary>
        /// Gets the <see cref="Frame"/> of the control.
        /// </summary>
        public Frame Frame
        {
            get { return SerializationObject as Frame; }
        }

        /// <summary>
        /// Gets the scripts for the frame.
        /// </summary>
        public ScriptContainer ScriptContainer
        {
            get { return Frame.ScriptContainer; }
        }

        /// <summary>
        /// Gets the default size of a FrameXML control.
        /// </summary>
        /// <value></value>
        protected override Size DefaultSize
        {
            get { return new Size(200, 200); }
        }

        /// <summary>
        /// Gets the actions for the control.
        /// </summary>
        /// <returns>
        /// An array of <see cref="Actions.Action"/> instances.
        /// </returns>
        public override Action[] GetActions()
        {
            var actions = new List<Action>
                              {
                                  new SetDefaultValueAction(this, "HitRectInset")
                                      {
                                          Category = "Create",
                                          DefaultValue = new Inset {Bottom = 1, Left = 1, Right = 1, Top = 1}
                                      },
                                  
                              };

            if (GetType() == typeof (FrameControl))
            {
                actions.AddRange(new Action[]
                                     {
                                         new MakeFrameMovableAction(this) {Category = "Behavior"},
                                         new SetDefaultValueAction(this, "TitleRegion")
                                      {
                                          Category = "Create",
                                          DefaultValue = new LayoutFrame
                                                         {
                                                             SetAllPoints = true,
                                                             Anchors =
                                                                 new[]
                                                                     {
                                                                         new Anchor {Point = FramePoint.TopLeft},
                                                                         new Anchor {Point = FramePoint.TopRight}
                                                                     },
                                                             SizeDimension = new Dimension
                                                                     {
                                                                         AbsDimension = new AbsDimension {X = 0, Y = 30}
                                                                     }
                                                         }
                                      },
                                     });
            }

            return actions.ToArray();
        }

        /// <summary>
        /// Draws the FrameXML control.
        /// </summary>
        /// <param name="graphics">The <see cref="FrameXmlGraphics"/> context to draw to.</param>
        /// <param name="rectangle">The <see cref="Rectangle"/> to draw to.</param>
        public override bool DrawControl(FrameXmlGraphics graphics, Rectangle rectangle)
        {
            if (Frame.Backdrop != null)
                return graphics.DrawBackdrop(Frame.Backdrop, rectangle);

            return false;
        }

        /// <summary>
        /// Gets the event names for a type.
        /// </summary>
        /// <param name="controlType">Type of the control.</param>
        /// <returns>Event names array</returns>
        public static EventName[] GetEventNames(Type controlType)
        {
            if (controlType == null)
                throw new ArgumentNullException("controlType");

            EventGroupAttribute eventGroupAttribute = controlType.GetCustomAttributes(typeof (EventGroupAttribute), false).OfType<EventGroupAttribute>().SingleOrDefault();
            return eventGroupAttribute != null ? eventGroupAttribute.GetEventNames() : null;
        }
    }
}